package com.roger.uia;

import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiScrollable;
import android.support.test.uiautomator.UiSelector;
import android.util.Log;

import com.roger.uia.helper.UiBase;
import com.roger.uia.helper.util.FileUtils;
import com.roger.uia.helper.util.LogUtils;
import com.roger.uia.helper.util.StrUtils;
import com.roger.uia.helper.UiWatch;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import static com.roger.uia.helper.UiBase.mDevice;
import static com.roger.uia.helper.UiBase.waitTime;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class TestWifiStress {
    private static final String TAG =TestWifiStress.class.getSimpleName();
    private String fileTestPath = Environment.getExternalStorageDirectory() + "/testWifi/";
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
    private Date date1,date2;
    private int pFlag=0;

    @BeforeClass
    public static void beforeClass() throws Throwable {
        if(!mDevice.isScreenOn()) mDevice.wakeUp();
        mDevice.pressHome();
    }

    @Before
    public void setUp()  {
        Log.d(TAG,"-- set up --");
        FileUtils.getPermission();
        UiWatch.getWatcher().runErrorWatcher();
        UiWatch.getWatcher().runSpecialWatcher();
    }

    @After
    public void tearDown() {
        Log.d(TAG,"-- tear down --");
        UiWatch.getWatcher().removeErrorWatcher();
        UiWatch.getWatcher().removeSpecialWatcher();
    }

    @AfterClass
    public static void afterClass() throws Throwable {
        mDevice.pressHome();
    }

    @Test
    public void StressTest01_connectWifi() throws Throwable {
        String desc=getJsonString(fileTestPath+"config.json","desc");
        String isTest=getJsonString(fileTestPath+"config.json","b1");
        String name=getJsonString(fileTestPath+"config.json","wifi1");
        String pwd=getJsonString(fileTestPath+"config.json","wifiPwd1");
        String times=getJsonString(fileTestPath+"config.json","times");
        String success="(?i)"+name+",Connected.*|"+name+",已连接.*";
        if(isTest.equals("false")){
            Log.d(TAG,"test canceled");
        }else{
            FileUtils.deleteFile(fileTestPath+ "result/connectWifi.html");
            FileUtils.writeFile(fileTestPath + "result/connectWifi.html",reportHead(desc));
            for(int i=0;i<Integer.valueOf(times);i++){
                try {
                    LogUtils.logcat(fileTestPath+ "logs/",String.valueOf(i+1)+"_ConnectWifi.txt");
                    date1=new Date(System.currentTimeMillis());
                    removeWifi();
                    enterWLAN();
                    SystemClock.sleep(waitTime*5);
                    UiObject menuText =UiBase.mDevice.findObject(new UiSelector().textMatches(name));
                    UiScrollable secMenuList = new UiScrollable(new UiSelector().resourceId(StrUtils.settingList));
                    for(int m=0;m<6;m++){
                        if(!menuText.exists()){
                            secMenuList.scrollIntoView(menuText);
                        }else{
                            menuText.clickAndWaitForNewWindow();
                            break;
                        }
                    }
                    date1=new Date(System.currentTimeMillis());
                    date2=new Date(System.currentTimeMillis());
                    if(!pwd.equals("")){
                        UiBase.inputTxtToObj(UiBase.objSelect[3],StrUtils.password,pwd);
                        UiBase.waitClickObj(UiBase.objSelect[2],StrUtils.connect,3);
                        date1=new Date(System.currentTimeMillis());
                    }
                    SystemClock.sleep(waitTime);
                    Log.d(TAG,"connect wifi start");
                    for(int j=0;j<=100;j++){
                        SystemClock.sleep(100);
                        if(UiBase.existObj(UiBase.objSelect[6],success)){
                            date2=new Date(System.currentTimeMillis());
                            long date3=date2.getTime()-date1.getTime();
                            FileUtils.writeFile(fileTestPath + "result/connectWifi.html",testResult(String.valueOf(i+1),"Pass",String.valueOf(date3)+"ms",dateFormat.format(date1),dateFormat.format(date2)));
                            break;
                        }
                        if(j==100){
                            date2=new Date(System.currentTimeMillis());
                            FileUtils.writeFile(fileTestPath + "result/connectWifi.html",testResult(String.valueOf(i+1),"Fail","connect time out 30s!",dateFormat.format(date1),dateFormat.format(date2)));
                            FileUtils.takeScreenPicTo(fileTestPath+ "pic/","ConnectWifi"+String.valueOf(i+1));
                        }
                    }
                   LogUtils.delLog(fileTestPath+ "logs/",String.valueOf(i+1)+"_ConnectWifi.txt");
                }catch (Throwable e){
                    e.printStackTrace();
                    LogUtils.stopLogCat();
                    date2=new Date(System.currentTimeMillis());
                    FileUtils.writeFile(fileTestPath + "result/connectWifi.html",testResult(String.valueOf(i+1),"Fail","not find the wifi:"+name,dateFormat.format(date1),dateFormat.format(date2)));
                    FileUtils.takeScreenPicTo(fileTestPath+ "pic/","ConnectWifi"+String.valueOf(i+1));
                    mDevice.pressHome();
                }finally {
                    removeWifi();
                }
            }
            FileUtils.writeFile(fileTestPath + "result/connectWifi.html",reportEnd());
        }
    }


    @Test
    public void StressTest02_switchWifi() throws Throwable {
        String desc=getJsonString(fileTestPath+"config.json","desc");
        String isTest=getJsonString(fileTestPath+"config.json","b2");
        String name1=getJsonString(fileTestPath+"config.json","wifi1");
        String pwd1=getJsonString(fileTestPath+"config.json","wifiPwd1");
        String name2=getJsonString(fileTestPath+"config.json","wifi2");
        String pwd2=getJsonString(fileTestPath+"config.json","wifiPwd2");
        String times=getJsonString(fileTestPath+"config.json","times");
        String success1="(?i)"+name1+",Connected.*|"+name1+",已连接.*";
        String success2="(?i)"+name2+",Connected.*|"+name2+",已连接.*";
        if(isTest.equals("false")){
            Log.d(TAG,"test canceled");
        }else{
            FileUtils.deleteFile(fileTestPath+ "result/switchWifi.html");
            FileUtils.writeFile(fileTestPath + "result/switchWifi.html",reportHead(desc));
            for(int i=0;i<Integer.valueOf(times);i++) {
                try {
                    LogUtils.logcat(fileTestPath+ "logs/",String.valueOf(i+1)+"_switchWifi.txt");
                    //连接ap1
                    pFlag=0;
                    date1=new Date(System.currentTimeMillis());
                    removeWifi();
                    enterWLAN();
                    SystemClock.sleep(waitTime*5);
                    UiObject menuText = UiBase.mDevice.findObject(new UiSelector().textMatches(name1));
                    UiScrollable secMenuList = new UiScrollable(new UiSelector().resourceId(StrUtils.settingList));
                    for(int m=0;m<6;m++){
                        if(!menuText.exists()){
                            secMenuList.scrollIntoView(menuText);
                        }else{
                            menuText.clickAndWaitForNewWindow();
                            break;
                        }
                    }

                    date1 = new Date(System.currentTimeMillis());
                    date2 = new Date(System.currentTimeMillis());
                    if (!pwd1.equals("")) {
                        UiBase.inputTxtToObj(UiBase.objSelect[3],StrUtils.password,pwd1);
                        UiBase.waitClickObj(UiBase.objSelect[2],StrUtils.connect,3);
                        date1 = new Date(System.currentTimeMillis());
                    }
                    SystemClock.sleep(waitTime);
                    for (int j = 0; j <= 100; j++) {
                        SystemClock.sleep(100);
                        if (UiBase.existObj(UiBase.objSelect[6],success1)) {
                            date2 = new Date(System.currentTimeMillis());
                            long date3 = date2.getTime() - date1.getTime();
                            FileUtils.writeFile(fileTestPath + "result/switchWifi.html",testResult(String.valueOf(i+1)+".1","Pass",String.valueOf(date3)+"ms",dateFormat.format(date1),dateFormat.format(date2)));
                            break;
                        }
                        if (j == 100) {
                            date2=new Date(System.currentTimeMillis());
                            FileUtils.writeFile(fileTestPath + "result/switchWifi.html",testResult(String.valueOf(i+1)+".1","Fail","connect time out 30s!",dateFormat.format(date1),dateFormat.format(date2)));
                            FileUtils.takeScreenPicTo(fileTestPath+ "pic/","switchWifi_A"+String.valueOf(i+1));
                        }
                    }
                    pFlag=1;
                    SystemClock.sleep(waitTime*5);
                    //连接ap2
                    UiObject menuText1 =UiBase.mDevice.findObject(new UiSelector().textMatches(name2));
                    UiScrollable secMenuList1 = new UiScrollable(new UiSelector().resourceId(StrUtils.settingList));
                    for(int n=0;n<6;n++){
                        if(!menuText1.exists()){
                            secMenuList1.scrollIntoView(menuText1);
                        }else{
                            menuText1.clickAndWaitForNewWindow();
                            break;
                        }
                    }
                    date1=new Date(System.currentTimeMillis());
                    if(!pwd2.equals("")){
                        UiBase.inputTxtToObj(UiBase.objSelect[3],StrUtils.password,pwd2);
                        UiBase.waitClickObj(UiBase.objSelect[2],StrUtils.connect,3);
                        date1=new Date(System.currentTimeMillis());
                    }
                    SystemClock.sleep(waitTime);
                    for(int j=0;j<= 100;j++){
                        SystemClock.sleep(100);
                        if(UiBase.existObj(UiBase.objSelect[6],success2)){
                            date2=new Date(System.currentTimeMillis());
                            long date4=date2.getTime()-date1.getTime();
                            FileUtils.writeFile(fileTestPath + "result/switchWifi.html",testResult(String.valueOf(i+1)+".2","Pass",String.valueOf(date4)+"ms",dateFormat.format(date1),dateFormat.format(date2)));
                            break;
                        }
                        if(j == 100){
                            date2=new Date(System.currentTimeMillis());
                            FileUtils.writeFile(fileTestPath + "result/switchWifi.html",testResult(String.valueOf(i+1)+".2","Fail","connect time out 30s!",dateFormat.format(date1),dateFormat.format(date2)));
                            FileUtils.takeScreenPicTo(fileTestPath+ "pic/","switchWifi_B"+String.valueOf(i+1));
                        }
                    }
                    SystemClock.sleep(waitTime*5);
                    LogUtils.delLog(fileTestPath+ "logs/",String.valueOf(i+1)+"_switchWifi.txt");
                }catch (Throwable e) {
                    e.printStackTrace();
                    LogUtils.stopLogCat();
                    date2=new Date(System.currentTimeMillis());
                    if(pFlag==0){
                        FileUtils.writeFile(fileTestPath + "result/switchWifi.html",testResult(String.valueOf(i+1)+".1","Fail","not find the wifi:"+name1,dateFormat.format(date1),dateFormat.format(date2)));
                        FileUtils.writeFile(fileTestPath + "result/switchWifi.html",testResult(String.valueOf(i+1)+".2","Fail","stop test switch to:"+name2,dateFormat.format(date1),dateFormat.format(date2)));
                        FileUtils.takeScreenPicTo(fileTestPath+ "pic/","switchWifi_A"+String.valueOf(i+1));
                    }else {
                        FileUtils.writeFile(fileTestPath + "result/switchWifi.html",testResult(String.valueOf(i+1)+".2","Fail","not find the wifi:"+name2,dateFormat.format(date1),dateFormat.format(date2)));
                        FileUtils.takeScreenPicTo(fileTestPath+ "pic/","switchWifi_B"+String.valueOf(i+1));
                    }
                    mDevice.pressHome();
                } finally {
                    removeWifi();
                }
            }
            FileUtils.writeFile(fileTestPath + "result/switchWifi.html",reportEnd());
        }
    }

    //进入wifi搜索界面
    private void enterWLAN() throws Throwable {
        if (UiBase.existObj(UiBase.objSelect[2],StrUtils.wifi) && UiBase.existObj(UiBase.objSelect[3],StrUtils.frictionIcon)) {
            SystemClock.sleep(waitTime);
        } else {
            mDevice.pressHome();
            UiBase.openApp(StrUtils.settingPac);
            UiBase.waitObj(UiBase.objSelect[3],StrUtils.settingDashBoard,10);
            UiBase.scrollReidClickObj(StrUtils.settingDashBoard,UiBase.objSelect[2],StrUtils.settingNetwork);
            UiBase.waitClickObj(UiBase.objSelect[2],StrUtils.wifi,5);
            UiBase.waitObj(UiBase.objSelect[3],StrUtils.switch_widget,5);
            if (UiBase.getTxtFromObj(UiBase.objSelect[3],StrUtils.switch_widget).matches(StrUtils.off)) {
                UiBase.clickObj(UiBase.objSelect[3],StrUtils.switch_widget);
                SystemClock.sleep(waitTime * 10);
            }
            SystemClock.sleep(waitTime);
        }
    }

    //移除已保存的wifi
    private void removeWifi(){
        try{
            WifiManager wifiManager = (WifiManager) InstrumentationRegistry.getTargetContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
            List<WifiConfiguration> wifiConfigs = wifiManager.getConfiguredNetworks();
            if(!String.valueOf(wifiConfigs).equals("[]")){
                enterWLAN();
                UiScrollable secMenuList = new UiScrollable(new UiSelector().resourceId(StrUtils.settingList));
                for(int j=0;j<10;j++){
                    secMenuList.scrollIntoView(UiBase.getObj(UiBase.objSelect[2],StrUtils.savedWifi));
                    if(UiBase.existObj(UiBase.objSelect[2],StrUtils.savedWifi)) {
                        UiBase.clickObj(UiBase.objSelect[2],StrUtils.savedWifi);
                        for (WifiConfiguration wifiConfig : wifiConfigs) {
                            String name = String.valueOf(wifiConfig.SSID.replaceAll("\"",""));
                            Log.d(TAG,"remove wifi : "+ name);
                            if (UiBase.existObj(UiBase.objSelect[0],name)){
                                UiBase.clickObj(UiBase.objSelect[0],name);
                                UiBase.waitClickObj(UiBase.objSelect[2],StrUtils.forget,3);
                            }
                        }
                        break;
                    }else {
                        Log.d(TAG,"no find saved wifi");
                    }
                }
            }else{
                Log.d(TAG,"no saved wifi");
            }
        }catch (Throwable e){
            Log.d(TAG,"remove saved wifi fail");
            e.printStackTrace();
        }finally {
            mDevice.pressHome();
        }
    }


    // 解析json数据
    public String getJsonString(String Path,String thisId){
        String string=null;
        try {
            File file = new File(Path);
            FileInputStream isr = new FileInputStream(file);
            BufferedReader bf = new BufferedReader(new InputStreamReader(isr));
            String line = "";
            StringBuilder stringBuilder = new StringBuilder();
            while ((line = bf.readLine()) != null) {
                stringBuilder.append(line);
            }
            JSONObject root = new JSONObject(stringBuilder.toString());
            JSONArray array = root.getJSONArray("config");
            //JSONObject params = array.getJSONObject(0);
            //JSONArray paramsData = params.getJSONArray("params");
            for (int i = 0; i < array.length(); i++) {
                JSONObject data = array.getJSONObject(i);
                String id = data.getString("id");
                if (thisId.equals(id)) {
                    string = (data.getString("value"));
                }
            }
            bf.close();
            isr.close();
        } catch (IOException | JSONException e) {
            e.printStackTrace();
        }
        return string;
    }

    //report
    private String reportHead(String desc){
        String s="<html>\n" +
                "<head>\n" +
                "<title>"+desc+"</title>\n" +
                "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n" +
                "</head>\n" +
                "<body> \n" +
                "<table border=\"1\" width=\"100%\" ALIGN=\"CENTER\" cellpadding=\"0\" cellspacing=\"0\" style=\"border-collapse:collapse\">\n" +
                "<th style=\"word-break:break-all;width:100%\"  ALIGN=\"CENTER\" background=\"#0f0f0f\" colspan=\"5\">WIFI连接压力测试报告</th>\n" +
                "<tr style=\"word-break:break-all;background:#00BBFF\" ALIGN=\"CENTER\"><td style=\"width:10%\">次数</td><td style=\"width:10%\">连接结果</td><td style=\"width:20%\">连接时间/错误原因</td><td style=\"width:30%\">开始时间</td><td style=\"width:30%\">结束时间</td></tr>";
        return s;
    }

    private String testResult(String no, String result, String time, String sTime, String eTime){
        String s="";
        if(result.equals("Pass")){
            s = "<tr><td style=\"word-break:break-all;width:10%\"  ALIGN=\"CENTER\">"+no+"</td><td style=\"width:10%;color:#00FF00\"  ALIGN=\"CENTER\">"+result+"</td><td style=\"width:20%\"  ALIGN=\"CENTER\">"+time+"</td><td style=\"width:30%\"  ALIGN=\"CENTER\">"+sTime+"</td><td style=\"width:30%\"  ALIGN=\"CENTER\">"+eTime+"</td></tr>";
        }else {
            s = "<tr><td style=\"word-break:break-all;width:10%\"  ALIGN=\"CENTER\">"+no+"</td><td style=\"width:10%;color:#FF0000\"  ALIGN=\"CENTER\">"+result+"</td><td style=\"width:20%\"  ALIGN=\"CENTER\">"+time+"</td><td style=\"width:30%\"  ALIGN=\"CENTER\">"+sTime+"</td><td style=\"width:30%\"  ALIGN=\"CENTER\">"+eTime+"</td></tr>";
        }
        return s;
    }

    private String reportEnd(){
        String s = "</table>\n" +
                "</body>\n" +
                "</html>\n";
        return s;
    }

}
